/* Copyright (c) 2009-2010, Real-Time Innovations, Inc.
 * Copyright (c) 2010, Object Management Group, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - Neither the names of the above copyright holders nor the names of their
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL A COPYRIGHT HOLDER OR CONTRIBUTOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <omg/dds.hpp>
#include <example_type.hpp>

using dds::core::InstanceHandle;
using dds::core::policy::Reliability;
using dds::domain::DomainParticipant;
using dds::domain::TheParticipantFactory;
using dds::topic::Topic;
using dds::pub::DataWriter;
using dds::pub::DataWriterListener;
using dds::pub::DataWriterQos;
using dds::pub::LivelinessLostStatus;
using dds::pub::OfferedDeadlineMissedStatus;
using dds::pub::OfferedIncompatibleQosStatus;
using dds::pub::PublicationMatchedStatus;
using dds::pub::Publisher;


class MyListener : public DataWriterListener<Foo>
{
    virtual void on_offered_deadline_missed(const DataWriter<Foo>& writer, 
                                            const OfferedDeadlineMissedStatus& status)
    {
        // empty
    }

    virtual void on_offered_incompatible_qos(const DataWriter<Foo>& writer, 
                                             const OfferedIncompatibleQosStatus& status)
    {
        // empty
    }

    virtual void on_liveliness_lost(const DataWriter<Foo>& writer, 
                                    const LivelinessLostStatus& status)
    {
        // empty
    }
    
    virtual void on_publication_matched(const DataWriter<Foo>& writer, 
                                        const PublicationMatchedStatus& status)
    {
        // empty
    }
};


static void pub_example()
{
    // --- Creation --- //
    DomainParticipant dp = TheParticipantFactory().create_participant();
    Publisher pub = dp.create_publisher();
    DataWriterQos dwq = pub.default_data_writer_qos();
    dwq.reliability().kind(Reliability::RELIABLE_KIND);
    // Listeners referred to by pointer: the user owns the memory.
    DataWriterListener<Foo>* dwl = new MyListener();
    Topic<Foo> tp = dp.create_topic<Foo>("My Topic");
    DataWriter<Foo> dw = pub.create_datawriter(tp, dwq, dwl);

    // --- Writing --- //
    Foo data;
    // Write data by itself and let middleware infer instance...
    dw.write(data);
    // ...or register explicitly and provide the handle later:
    InstanceHandle hd = dw.register_instance(data);
    // Concept of nil/null looks the same for every type:
    if (hd == dds::core::null) {
        // do something...
    }
    dw.write(data, hd);
    /* InstanceWriter concept is useful for some usage patterns. For those
     * patterns, it can be layered on. (Can't replace InstanceHandle with
     * InstanceWriter anyway, because handle appears in status and other
     * places.) InstanceWriter utility could be standard or could be open
     * source -- a "boost for DDS" (evolved from SIMD?) would be awesome.
     */
    //InstanceWriter<Foo> iw(dw, hd);
    //iw.write(data);

    // --- Navigation --- //
    Publisher parent = dw.parent();
    if (pub == parent) { /* expected */ }

    DataWriter<Foo> child_static_safe = parent.lookup_datawriter(tp);
    if (child_static_safe == dw) { /* expected */ }

    DataWriter<Foo> child_runtime_safe =
        parent.lookup_datawriter<Foo>("My Topic");
    if (child_runtime_safe == dw) { /* expected */ }

    // --- Shutdown --- //
    dp.close();
}
